package net.wicp.tams.common.others;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import freemarker.cache.ClassTemplateLoader;
import net.wicp.tams.common.Conf;
import net.wicp.tams.common.Result;
import net.wicp.tams.common.apiext.FreemarkUtil;
import net.wicp.tams.common.apiext.IOUtil;
import net.wicp.tams.common.apiext.StringUtil;
import net.wicp.tams.common.http.HttpClient;
import net.wicp.tams.common.http.HttpResult;
import net.wicp.tams.common.http.HttpThread;

public abstract class JenkinsUtil {
	static {
		ClassTemplateLoader classLoadLoader = new ClassTemplateLoader(JenkinsUtil.class, "/template/jenkins");
		FreemarkUtil.getInst().addLoads(classLoadLoader);
	}

	public static String getScriptGit(String repo, String branch) {
		String temp = "\r\n stage('git clone'){\r\n" + "        //check CODE\r\n" + "       git branch: '" + branch
				+ "', credentialsId:'" + Conf.get("common.others.jenkins.git.credentialsId") + "',url: '" + repo
				+ "'\r\n" + "}\r\n";
		return temp;
	}

	public static String getScriptBuild(Boolean isSkipTest) {
		if (isSkipTest == null) {
			isSkipTest = true;// 默认跳过测试
		}
		String temp = "\r\n stage('mvn build'){\r\n        sh \"mvn clean install -Dmaven.test.skip=" + isSkipTest
				+ "\"\r\n" + "    }\r\n";
		return temp;
	}

	public static String getScriptDeploy() {
		String temp = "\r\n stage('docker build'){\r\n        sh \"mvn deploy \"\r\n" + "    }\r\n";
		return temp;
	}

	public static String getScriptDockerBuild() {
		String temp = "\r\n stage('docker build'){\r\n        sh \"mvn ts:dockbuild\"\r\n" + "    }\r\n";
		return temp;
	}

	public static String getScriptAddGit(String repo, String branch) {
		String temp = "\r\n stage('git push'){\r\n        sh \"mvn ts:addgit -Drepository=" + repo + " -Dbranch="
				+ branch + " \"\r\n" + "    }\r\n";
		return temp;
	}

	// catalog=group+projectName
	public static String getScriptDockerPush(String group, String projectName, String tag) {
		String catalog = IOUtil.mergeFolderAndFilePath(group, projectName);
		return getScriptDockerPush(catalog, tag);
	}

	public static String getScriptDockerPush(String catalog, String tag) {
		String rep = IOUtil.mergeFolderAndFilePath(Conf.get("common.others.docker.registry"), catalog);
		String temp = "";
		if (StringUtil.isNull(tag)) {
			temp = String.format(
					"\r\n stage('docker push'){\r\n        sh \"mvn ts:dockpush -Drep=%s\"\r\n" + "    }\r\n", rep);
		} else {
			temp = String.format(
					"\r\n stage('docker push'){\r\n        sh \"mvn ts:dockpush -Drep=%s -Dtag=%s\"\r\n" + "    }\r\n",
					rep, tag);
		}
		return temp;
	}

	public static String getScriptAddRc(String msgid, String namespace) {
		String callback = Conf.get("common.others.jenkins.boom.callback");
		String temp = "\r\n stage('k8s addrc'){\r\n        sh \"mvn ts:addrc ";
		if (StringUtil.isNotNull(msgid)) {
			temp += String.format(" -Dcallback=%s  -Dmsgid=%s", callback, msgid);
		}

		if (StringUtil.isNotNull(namespace)) {
			temp += String.format(" -Dnamespace=%s", namespace);
		}
		temp += "\"\r\n  }\r\n";
		return temp;
	}

	public static String getScriptAddSvc(String msgid, String namespace) {
		String callback = Conf.get("common.others.jenkins.boom.callback");
		String temp = "\r\n stage('k8s addsvc'){\r\n        sh \"mvn ts:addsvc ";
		if (StringUtil.isNotNull(msgid)) {
			temp += String.format(" -Dcallback=%s  -Dmsgid=%s", callback, msgid);
		}

		if (StringUtil.isNotNull(namespace)) {
			temp += String.format(" -Dnamespace=%s", namespace);
		}
		temp += "\"\r\n  }\r\n";
		return temp;
	}

	public static String getSucScript() {
		String temp = "\r\n stage('sucess'){\r\n        echo \"do all sucess ......\" \r\n  }\r\n";
		return temp;
	}

	/***
	 * 得到jenkins模板
	 * 
	 * @param stages
	 *            步骤
	 * @return jenkinsscript
	 */
	public static String getTemp(String... stages) {
		StringBuffer buff = new StringBuffer("node{\r\n");
		
		buff.append("def mvnHome = tool '"+Conf.get("common.others.jenkins.tool.jdkid")+"'\r\n");
		buff.append("def jdkHome = tool '"+Conf.get("common.others.jenkins.tool.mavenid")+"'\r\n");
		buff.append("env.PATH = \"${mvnHome}/bin:${jdkHome}/bin:${env.PATH}\"\r\n");
		
		for (String stage : stages) {
			buff.append(stage);
		}
		buff.append("}");
		return buff.toString();
	}

	/**
	 * 创建一个job
	 * 
	 * @param foldPath
	 *            job所在目录
	 * @param jobName
	 *            job名字
	 * @param configXML
	 *            job配置信息
	 * @return 结果
	 */
	public static Result createJob(String foldPath, String jobName, String configXML) {
		String url = IOUtil.mergeFolderAndFilePath(Conf.get("common.others.jenkins.server.url"),
				String.format("%screateItem?name=%s", jobPathPar(foldPath), jobName));
		return doPost(url, configXML);
	}

	/***
	 * 删除一个job
	 * 
	 * @param jobpath
	 *            jobpath
	 * @return 结果
	 */
	public static Result deleteJob(String jobpath) {
		String url = String.format("%s/%sdoDelete", Conf.get("common.others.jenkins.server.url"), jobPathPar(jobpath));
		return doPost(url, null);
	}

	/**
	 * 创建一个目录
	 * 
	 * @param foldPath
	 *            目录所在路径，空为根目录
	 * @param foldName
	 *            目录名
	 * @param displayName
	 *            目录显示名
	 * @param description
	 *            目录描述
	 * @return 结果
	 */
	public static Result createFloder(String foldPath, String foldName, String displayName, String description) {
		String jobstr1 = readJob(foldPath);
		if (jobstr1.contains("404")) {
			return Result.getError("父目录不存在:" + foldPath);
		}
		String path = IOUtil.mergeFolderAndFilePath(StringUtil.hasNull(foldPath, "/"), foldName);
		String jobstr2 = readJob(path);
		if (jobstr2.contains("com.cloudbees.hudson.plugins.folder.Folder")) {
			return Result.getSuc("此目录已存在:" + path);
		}
		Map<String, String> input = new HashMap<>();
		input.put("displayName", StringUtil.hasNull(displayName, ""));
		input.put("description", StringUtil.hasNull(description, ""));
		String strtrue = FreemarkUtil.getInst().doProcess("floder.flt", input);
		return createJob(foldPath, foldName, strtrue);
	}

	/***
	 * 创建一个目录 简单版
	 * 
	 * @param foldPathAll
	 *            要创建的目录的全路径
	 * @param description
	 *            目录描述
	 * @param isForce
	 *            是否强制创建父目录
	 * @return 结果
	 */
	public static Result createFloder(String foldPathAll, String description, boolean isForce) {
		String jenkinspath = foldPathAll;
		jenkinspath = jenkinspath.endsWith("/") ? jenkinspath.substring(0, jenkinspath.length() - 1) : jenkinspath;
		jenkinspath = jenkinspath.startsWith("/") ? jenkinspath : "/" + jenkinspath;
		int index = jenkinspath.lastIndexOf("/");
		String name = jenkinspath.substring(index + 1);

		String foldPath = index == -1 ? null : jenkinspath.substring(0, index);
		if (isForce) {
			String[] split = foldPath.split("/");
			String root = "";
			for (String path : split) {
				if (StringUtil.isNull(false, path)) {
					continue;
				}
				Result createFloder = createFloder(root, path, path, "auto create");
				root += "/" + path;
				if (!createFloder.isSuc()) {
					return createFloder;
				}
			}
		}
		return createFloder(foldPath, name, name, description);
	}

	// 创建pipeline
	public static Result createPipeline(String foldPath, String jobName, String script) {
		Map<String, String> input = new HashMap<>();
		input.put("script", StringUtil.hasNull(script, ""));
		String strtrue = FreemarkUtil.getInst().doProcess("pipeline.flt", input);
		return createJob(foldPath, jobName, strtrue);
	}

	/***
	 * 读job的配置信息
	 * 
	 * @param jobpath
	 *            job的路径，如 /application
	 * @return job信息
	 */
	public static String readJob(String jobpath) {
		String temp = jobPathPar(jobpath);
		String url = IOUtil.mergeFolderAndFilePath(Conf.get("common.others.jenkins.server.url"),
				String.format("%sconfig.xml", temp));
		HttpResult http = HttpClient.doGet(url);
		String retstr = http.getBodyStr();
		return retstr;
	}

	/**
	 * 停止一个流程
	 * 
	 * @param jobpath
	 *            jobpath
	 * @return 结果
	 */
	public static Result stopBuild(String jobpath) {
		String url = String.format("%s/%s1/stop", Conf.get("common.others.jenkins.server.url"), jobPathPar(jobpath));
		return doPost(url, null);
	}

	/**
	 * 触发起动流程
	 * 
	 * @param flowPath
	 *            流程的路径
	 * @param viewName
	 *            流程的view
	 * @return 结果
	 */
	public static Result triggerBuild(String flowPath, String viewName) {
		String url = String.format("%s/%sview/%s/gridBuilder/build", Conf.get("common.others.jenkins.server.url"),
				jobPathPar(flowPath), viewName);
		return doPost(url, null);
	}

	/***
	 * 启动一个job
	 * 
	 * @param jobpath
	 *            流程的路径
	 * @return 结果
	 */
	public static Result triggerBuild(String jobpath) {
		String url = String.format("%s/%sbuild", Conf.get("common.others.jenkins.server.url"), jobPathPar(jobpath));
		return doPost(url, null);
	}

	/***
	 * 得到目录下所有job,TODO xml分隔
	 * 
	 * @param folderpath
	 *            目录的路径
	 * @return 所有job
	 */
	public static List<String> listJobs(String folderpath) {
		String url = String.format("%s/%sapi/xml", Conf.get("common.others.jenkins.server.url"),
				jobPathPar(folderpath));
		HttpThread thread = HttpClient.doPostXml(url, null);
		String jsonResponse = thread.call().getBodyStr();
		List<String> jobList = new ArrayList<String>();
		String[] jobs = jsonResponse.split("job>");
		for (String job : jobs) {
			String[] names = job.split("name>");
			if (names.length == 3) {
				String name = names[1];
				name = name.substring(0, name.length() - 2);
				jobList.add(name);
			}
		}
		return jobList;
	}

	private static String jobPathPar(String jobpath) {
		if (StringUtil.isNull(jobpath)) {
			return "";
		}
		StringBuffer temp = new StringBuffer();
		String[] jobpathAry = jobpath.split("\\/");
		for (String job : jobpathAry) {
			if (StringUtil.isNotNull(job)) {
				temp.append(String.format("job/%s/", job));
			}
		}
		// String path = IOUtil.mergeFolderAndFilePath("job", jobpath) + "/";
		String path = temp.toString();
		return path;
	}

	private static Result doPost(String url, String configXML) {
		HttpThread thread = HttpClient.doPostXml(url, configXML);
		String retstr = thread.call().getBodyStr();
		if (StringUtil.isNull(retstr)) {
			return Result.getSuc();
		} else {
			return Result.getError("执行失败").setRetObjs(retstr);
		}

		/*
		 * URI uri = URI.create(url); HttpHost host = new HttpHost(uri.getHost(),
		 * uri.getPort(), uri.getScheme()); CredentialsProvider credsProvider = new
		 * BasicCredentialsProvider(); credsProvider.setCredentials(new
		 * AuthScope(uri.getHost(), uri.getPort()), new
		 * UsernamePasswordCredentials("rjzjh", "mfkwcwiqpl")); // Create AuthCache
		 * instance AuthCache authCache = new BasicAuthCache(); // Generate BASIC scheme
		 * object and add it to the local auth cache BasicScheme basicAuth = new
		 * BasicScheme(); authCache.put(host, basicAuth); CloseableHttpClient httpClient
		 * = HttpClients.custom().setDefaultCredentialsProvider(credsProvider). build();
		 * HttpPost httpPost = new HttpPost(uri); //FileEntity entity = new
		 * FileEntity(new File("E:\\config.xml")); //httpPost.setEntity(entity);
		 * 
		 * if (StringUtil.isNotNull(configXML)) { StringEntity se = new
		 * StringEntity(configXML, "UTF-8"); // se.setContentType(CONTENT_TYPE);
		 * se.setContentEncoding(new BasicHeader(HTTP.CONTENT_TYPE, "application/xml"));
		 * httpPost.setEntity(se); }
		 * 
		 * httpPost.setHeader("Content-Type", "application/xml;charset=UTF-8"); //
		 * httpPost.setEntity(reqEntity); // Add AuthCache to the execution context
		 * HttpClientContext localContext = HttpClientContext.create();
		 * localContext.setAuthCache(authCache);
		 * 
		 * try { HttpResponse response = httpClient.execute(host, httpPost,
		 * localContext); String result = EntityUtils.toString(response.getEntity());
		 * return Result.getSuc(); }catch (Exception e) { return Result.getError("aa");
		 * }
		 */

	}
}
